﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using Microsoft.Devices;
using System.Threading;
using System.Windows.Media.Imaging;
using Gif.Components;
using System.IO;

namespace luGIF微电影.View
{
    public partial class FromCameraPage : PhoneApplicationPage
    {
        PhotoCamera cam = new PhotoCamera();
        private static ManualResetEvent pauseFramesEvent = new ManualResetEvent(true);
        private WriteableBitmap wb;
        private Timer timer;
        private bool started = false;



        List<WriteableBitmap> bitmapList = new List<WriteableBitmap>();
        AnimatedGifEncoder encoder = new AnimatedGifEncoder();
        FileStream gif;
        public FromCameraPage()
        {
            InitializeComponent();
            timer = new Timer(MyTimerCallback, capturedImage, 1000, 200);

        }
        //Code for camera initialization event, and setting the source for the viewfinder
        protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
        {

            // Check to see if the camera is available on the device.
            if ((PhotoCamera.IsCameraTypeSupported(CameraType.Primary) == true) ||
                 (PhotoCamera.IsCameraTypeSupported(CameraType.FrontFacing) == true))
            {
                // Initialize the default camera.
                cam = new Microsoft.Devices.PhotoCamera();
                //Event is fired when the PhotoCamera object has been initialized
                cam.Initialized += new EventHandler<Microsoft.Devices.CameraOperationCompletedEventArgs>(cam_Initialized);

                
                //Set the VideoBrush source to the camera
                cameraViewBrush.SetSource(cam);
            }
            else
            {
                // The camera is not supported on the device.
                this.Dispatcher.BeginInvoke(delegate()
                {
                });
            }
        }
        protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
        {
            // Dispose of camera and media objects.
            try
            {
                gif.Close();
            }
            catch (Exception ee)
            { }
            try
            {
                cam.Dispose();
            }
            catch (Exception ee)
            { }

            base.OnNavigatedFrom(e);
        }
        void cam_Initialized(object sender, Microsoft.Devices.CameraOperationCompletedEventArgs e)
        {
            
            if (e.Succeeded)
            {
                var res = from resolution in cam.AvailableResolutions
                          where resolution.Width == 320
                          select resolution;

                cam.Resolution = res.First();
                

                this.Dispatcher.BeginInvoke(delegate()
                {
                    txtDebug.Text = "Camera initialized";
                });

            }
        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            Button b = sender as Button;
            wb = new WriteableBitmap((int)cam.PreviewResolution.Width, (int)cam.PreviewResolution.Height);
            this.capturedImage.Source = wb;
            if (b.Content.Equals("Start"))
            {
                started = true;
                b.Content = "Stop";
            }
            else
            {
                started = false;
                b.Content = "Start";
                String outputFilePath = DateTime.Now.Ticks.ToString() + ".gif";
                gif = encoder.Start(outputFilePath);
                encoder.SetDelay(200);
                encoder.SetRepeat(0);
                txtDebug.Text = bitmapList.Count.ToString();
                foreach (WriteableBitmap w in bitmapList)
                {
                    encoder.AddFrame(w);
                }
                encoder.Finish();
            }

        }
        private void MyTimerCallback(object state)
        {
            if (started)
            {
                int[] ARGBPx = new int[(int)cam.PreviewResolution.Width * (int)cam.PreviewResolution.Height];
                
                try
                {
                    PhotoCamera phCam = (PhotoCamera)cam;
                    pauseFramesEvent.WaitOne();

                    // Copies the current viewfinder frame into a buffer for further manipulation.
                    phCam.GetPreviewBufferArgb32(ARGBPx);

                    // Conversion to grayscale.

                    pauseFramesEvent.Reset();


                    Deployment.Current.Dispatcher.BeginInvoke(delegate()
                    {
                        // Copy to WriteableBitmap.
                        ARGBPx.CopyTo(wb.Pixels, 0);
                        wb.Invalidate();
                        pauseFramesEvent.Set();


                        ScaleTransform trans = new ScaleTransform();
                        trans.CenterX = 0;
                        trans.CenterX = 0;
                        trans.ScaleY = 0.5;
                        trans.ScaleX = 0.5;
                        Image temp = new Image();
                        temp.Source = wb;
                        WriteableBitmap newbitmap = new WriteableBitmap((int)cam.PreviewResolution.Width /2, (int)cam.PreviewResolution.Height/2);
                        newbitmap.Render(temp, trans);
                        newbitmap.Invalidate();
                        bitmapList.Add(new WriteableBitmap(newbitmap));
                    });
                    


                }
                catch (Exception e)
                {
                    this.Dispatcher.BeginInvoke(delegate()
                    {
                        // Display error message.
                        txtDebug.Text = e.Message;
                    });
                }
            }
        }
    }
}